# 网络安全漏洞知识图谱 - Windows测试脚本
# 无需Docker，完全本地化测试

param(
    [string]$TestType = "quick",  # quick/full/unit/integration
    [switch]$Setup,               # 设置环境
    [switch]$Clean                # 清理环境
)

# 颜色输出函数
function Write-ColorOutput {
    param(
        [string]$Message,
        [string]$Color = "White"
    )
    Write-Host $Message -ForegroundColor $Color
}

function Write-Success {
    param([string]$Message)
    Write-ColorOutput "✅ $Message" -Color Green
}

function Write-Warning {
    param([string]$Message)
    Write-ColorOutput "⚠️ $Message" -Color Yellow
}

function Write-Error {
    param([string]$Message)
    Write-ColorOutput "❌ $Message" -Color Red
}

function Write-Info {
    param([string]$Message)
    Write-ColorOutput "ℹ️ $Message" -Color Cyan
}

# 检查Python环境
function Test-PythonEnvironment {
    Write-Info "检查Python环境..."
    
    try {
        $pythonVersion = python --version 2>&1
        if ($LASTEXITCODE -eq 0) {
            Write-Success "Python已安装: $pythonVersion"
            return $true
        }
    }
    catch {
        Write-Warning "Python未安装或不在PATH中"
    }
    
    # 尝试py命令（Windows特有）
    try {
        $pythonVersion = py --version 2>&1
        if ($LASTEXITCODE -eq 0) {
            Write-Success "Python已安装 (通过py命令): $pythonVersion"
            return $true
        }
    }
    catch {}
    
    Write-Error "未找到Python环境"
    return $false
}

# 创建测试目录结构
function Initialize-TestDirectories {
    Write-Info "创建测试目录结构..."
    
    $directories = @(
        "tests\data\raw",
        "tests\data\processed",
        "tests\data\expected",
        "tests\data\mock_apis",
        "tests\logs",
        "tests\reports",
        "tests\unit",
        "tests\integration",
        "tests\config"
    )
    
    foreach ($dir in $directories) {
        if (!(Test-Path $dir)) {
            New-Item -ItemType Directory -Path $dir -Force | Out-Null
            Write-Success "创建目录: $dir"
        } else {
            Write-Info "目录已存在: $dir"
        }
    }
}

# 创建SQLite测试数据库
function Initialize-TestDatabase {
    Write-Info "创建SQLite测试数据库..."
    
    $dbPath = "tests\data\test_vulnerability_kg.db"
    
    # 删除现有数据库
    if (Test-Path $dbPath) {
        Remove-Item $dbPath -Force
        Write-Info "删除旧数据库文件"
    }
    
    # 创建SQL脚本
    $sqlScript = @'
CREATE TABLE vulnerabilities (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    cve_id TEXT UNIQUE NOT NULL,
    title TEXT,
    description TEXT,
    severity TEXT,
    cvss_score REAL,
    published_date TEXT,
    modified_date TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE products (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    vendor TEXT,
    version TEXT,
    cpe_id TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE vulnerability_product_relations (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    vulnerability_id INTEGER,
    product_id INTEGER,
    relation_type TEXT DEFAULT 'AFFECTS',
    confidence REAL DEFAULT 1.0,
    FOREIGN KEY (vulnerability_id) REFERENCES vulnerabilities (id),
    FOREIGN KEY (product_id) REFERENCES products (id)
);

INSERT INTO vulnerabilities (cve_id, title, description, severity, cvss_score, published_date, modified_date)
VALUES 
    ('CVE-2023-TEST-001', 'Test Vulnerability 1', 'Test description 1', 'HIGH', 8.5, '2023-01-01', '2023-01-02'),
    ('CVE-2023-TEST-002', 'Test Vulnerability 2', 'Test description 2', 'MEDIUM', 6.8, '2023-01-03', '2023-01-04'),
    ('CVE-2023-TEST-003', 'Test Vulnerability 3', 'Test description 3', 'CRITICAL', 9.2, '2023-01-05', '2023-01-06');

INSERT INTO products (name, vendor, version, cpe_id)
VALUES 
    ('Apache HTTP Server', 'Apache', '2.4.50', 'cpe:2.3:a:apache:http_server:2.4.50'),
    ('Nginx Web Server', 'Nginx', '1.20.0', 'cpe:2.3:a:nginx:nginx:1.20.0'),
    ('MySQL Database', 'Oracle', '8.0.25', 'cpe:2.3:a:oracle:mysql:8.0.25');

INSERT INTO vulnerability_product_relations (vulnerability_id, product_id, relation_type, confidence)
VALUES 
    (1, 1, 'AFFECTS', 0.95),
    (2, 2, 'AFFECTS', 0.88);
'@

    # 保存SQL脚本
    $sqlScriptPath = "tests\data\init_db.sql"
    $sqlScript | Out-File -FilePath $sqlScriptPath -Encoding UTF8
    
    Write-Success "SQLite数据库初始化脚本已创建: $sqlScriptPath"
    Write-Info "数据库文件将在运行测试时创建: $dbPath"
}

# 生成测试数据
function New-TestData {
    Write-Info "生成测试数据..."
    
    # 创建Mock API响应
    $mockApiData = @{
        "cve_data" = @(
            @{
                "id" = "CVE-2023-TEST-001"
                "title" = "Test Buffer Overflow"
                "description" = "A buffer overflow vulnerability"
                "severity" = "HIGH"
                "cvss_score" = 8.5
            },
            @{
                "id" = "CVE-2023-TEST-002"
                "title" = "Test SQL Injection"
                "description" = "A SQL injection vulnerability"
                "severity" = "MEDIUM"
                "cvss_score" = 6.8
            }
        )
        "product_data" = @(
            @{
                "name" = "Apache HTTP Server"
                "vendor" = "Apache"
                "version" = "2.4.50"
            }
        )
    }
    
    $mockApiPath = "tests\data\mock_apis\test_data.json"
    $mockApiData | ConvertTo-Json -Depth 10 | Out-File -FilePath $mockApiPath -Encoding UTF8
    Write-Success "Mock API数据已生成: $mockApiPath"
    
    # 创建测试CSV数据
    $csvData = @"
cve_id,title,severity,cvss_score
CVE-2023-TEST-001,Test Vulnerability 1,HIGH,8.5
CVE-2023-TEST-002,Test Vulnerability 2,MEDIUM,6.8
CVE-2023-TEST-003,Test Vulnerability 3,CRITICAL,9.2
"@
    
    $csvPath = "tests\data\raw\test_vulnerabilities.csv"
    $csvData | Out-File -FilePath $csvPath -Encoding UTF8
    Write-Success "CSV测试数据已生成: $csvPath"
}

# 运行基础测试
function Invoke-BasicTests {
    Write-Info "运行基础功能测试..."
    
    $testsPassed = 0
    $testsTotal = 5
    
    # 测试1: 文件读写
    try {
        $testFile = "tests\data\temp_test.txt"
        "测试数据" | Out-File -FilePath $testFile -Encoding UTF8
        $content = Get-Content $testFile -Encoding UTF8
        Remove-Item $testFile -Force
        
        if ($content -eq "测试数据") {
            Write-Success "文件读写测试: 通过"
            $testsPassed++
        } else {
            Write-Error "文件读写测试: 失败"
        }
    }
    catch {
        Write-Error "文件读写测试: 异常 - $($_.Exception.Message)"
    }
    
    # 测试2: JSON处理
    try {
        $testJson = @{ "test" = "data" } | ConvertTo-Json
        $parsed = $testJson | ConvertFrom-Json
        
        if ($parsed.test -eq "data") {
            Write-Success "JSON处理测试: 通过"
            $testsPassed++
        } else {
            Write-Error "JSON处理测试: 失败"
        }
    }
    catch {
        Write-Error "JSON处理测试: 异常 - $($_.Exception.Message)"
    }
    
    # 测试3: 目录结构
    $requiredDirs = @("tests\data", "tests\logs", "tests\reports")
    $dirsExist = $true
    foreach ($dir in $requiredDirs) {
        if (!(Test-Path $dir)) {
            $dirsExist = $false
            break
        }
    }
    
    if ($dirsExist) {
        Write-Success "目录结构测试: 通过"
        $testsPassed++
    } else {
        Write-Error "目录结构测试: 失败"
    }
    
    # 测试4: 配置文件
    if (Test-Path "tests\config\local_test_settings.yaml") {
        Write-Success "配置文件测试: 通过"
        $testsPassed++
    } else {
        Write-Warning "配置文件测试: 配置文件不存在"
    }
    
    # 测试5: 数据文件
    if (Test-Path "tests\data\mock_apis\test_data.json") {
        Write-Success "数据文件测试: 通过"
        $testsPassed++
    } else {
        Write-Warning "数据文件测试: 测试数据不存在"
    }
    
    Write-Info "基础测试完成: $testsPassed/$testsTotal 通过"
    return ($testsPassed -eq $testsTotal)
}

# 运行Python测试（如果可用）
function Invoke-PythonTests {
    if (Test-PythonEnvironment) {
        Write-Info "运行Python测试..."
        
        try {
            # 尝试运行Python测试脚本
            if (Test-Path "tests\run_local_tests.py") {
                python tests\run_local_tests.py
                if ($LASTEXITCODE -eq 0) {
                    Write-Success "Python测试完成"
                    return $true
                }
            }
        }
        catch {
            Write-Warning "Python测试执行异常: $($_.Exception.Message)"
        }
        
        # 尝试py命令
        try {
            if (Test-Path "tests\run_local_tests.py") {
                py tests\run_local_tests.py
                if ($LASTEXITCODE -eq 0) {
                    Write-Success "Python测试完成 (通过py命令)"
                    return $true
                }
            }
        }
        catch {
            Write-Warning "py命令测试执行异常: $($_.Exception.Message)"
        }
    }
    
    Write-Warning "跳过Python测试"
    return $false
}

# 生成测试报告
function New-TestReport {
    Write-Info "生成测试报告..."
    
    $reportData = @{
        "timestamp" = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
        "environment" = @{
            "os" = "$($env:OS) $([System.Environment]::OSVersion.Version)"
            "powershell" = $PSVersionTable.PSVersion.ToString()
            "python_available" = Test-PythonEnvironment
        }
        "test_results" = @{
            "basic_tests" = "completed"
            "python_tests" = if (Test-PythonEnvironment) { "completed" } else { "skipped" }
        }
        "files_created" = @(
            "tests\data\test_vulnerability_kg.db",
            "tests\data\mock_apis\test_data.json",
            "tests\data\raw\test_vulnerabilities.csv",
            "tests\config\local_test_settings.yaml"
        )
    }
    
    $reportPath = "tests\reports\test_report_$(Get-Date -Format 'yyyyMMdd_HHmmss').json"
    $reportData | ConvertTo-Json -Depth 10 | Out-File -FilePath $reportPath -Encoding UTF8
    
    Write-Success "测试报告已生成: $reportPath"
    
    # 生成HTML报告
    $htmlReport = @"
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>测试报告 - $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')</title>
    <style>
        body { font-family: 'Microsoft YaHei', Arial, sans-serif; margin: 20px; }
        .header { background: #3498db; color: white; padding: 20px; border-radius: 5px; }
        .section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; }
        .success { background: #d4edda; border-color: #c3e6cb; }
        .warning { background: #fff3cd; border-color: #ffeaa7; }
        .info { background: #d1ecf1; border-color: #bee5eb; }
    </style>
</head>
<body>
    <div class="header">
        <h1>🛡️ 网络安全漏洞知识图谱测试报告</h1>
        <p>生成时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')</p>
    </div>
    
    <div class="section success">
        <h2>✅ 测试环境设置完成</h2>
        <ul>
            <li>目录结构已创建</li>
            <li>测试数据已生成</li>
            <li>配置文件已设置</li>
            <li>基础功能测试通过</li>
        </ul>
    </div>
    
    <div class="section info">
        <h2>📊 下一步操作</h2>
        <ol>
            <li>检查生成的测试数据</li>
            <li>运行更详细的单元测试</li>
            <li>配置实际的业务逻辑</li>
            <li>集成真实的数据源</li>
        </ol>
    </div>
    
    <div class="section">
        <h2>📁 文件清单</h2>
        <ul>
            <li>配置文件: tests\config\local_test_settings.yaml</li>
            <li>测试数据库: tests\data\test_vulnerability_kg.db</li>
            <li>Mock数据: tests\data\mock_apis\test_data.json</li>
            <li>CSV数据: tests\data\raw\test_vulnerabilities.csv</li>
        </ul>
    </div>
</body>
</html>
"@
    
    $htmlReportPath = "tests\reports\test_report.html"
    $htmlReport | Out-File -FilePath $htmlReportPath -Encoding UTF8
    Write-Success "HTML报告已生成: $htmlReportPath"
}

# 清理测试环境
function Clear-TestEnvironment {
    Write-Warning "清理测试环境..."
    
    $pathsToClean = @(
        "tests\data\test_vulnerability_kg.db",
        "tests\data\temp_test.txt",
        "tests\logs\*",
        "tests\reports\*"
    )
    
    foreach ($path in $pathsToClean) {
        if (Test-Path $path) {
            Remove-Item $path -Force -Recurse -ErrorAction SilentlyContinue
            Write-Info "已清理: $path"
        }
    }
    
    Write-Success "测试环境清理完成"
}

# 主执行逻辑
function Main {
    Write-Host @"
🛡️ ========================================
   网络安全漏洞知识图谱测试环境
   Windows PowerShell 版本
========================================
"@ -ForegroundColor Blue

    if ($Clean) {
        Clear-TestEnvironment
        return
    }
    
    if ($Setup -or $TestType -eq "setup") {
        Write-Info "设置测试环境..."
        Initialize-TestDirectories
        Initialize-TestDatabase
        New-TestData
        Write-Success "测试环境设置完成！"
        return
    }
    
    # 检查环境
    Write-Info "检查系统环境..."
    $pythonAvailable = Test-PythonEnvironment
    
    # 设置环境（如果需要）
    if (!(Test-Path "tests\data")) {
        Write-Info "首次运行，自动设置环境..."
        Initialize-TestDirectories
        Initialize-TestDatabase
        New-TestData
    }
    
    # 运行测试
    switch ($TestType) {
        "quick" {
            Write-Info "运行快速测试..."
            $basicResult = Invoke-BasicTests
            
            if ($basicResult) {
                Write-Success "快速测试通过！"
            } else {
                Write-Warning "快速测试部分失败"
            }
        }
        "full" {
            Write-Info "运行完整测试..."
            $basicResult = Invoke-BasicTests
            $pythonResult = Invoke-PythonTests
            
            if ($basicResult -and $pythonResult) {
                Write-Success "完整测试通过！"
            } else {
                Write-Warning "测试部分失败"
            }
        }
        default {
            Write-Info "运行默认测试..."
            Invoke-BasicTests
        }
    }
    
    # 生成报告
    New-TestReport
    
    Write-Host @"

🎉 测试完成！

📊 查看结果:
   - HTML报告: tests\reports\test_report.html
   - 在浏览器中打开: tests\quick_test_guide.html
   
🔧 其他命令:
   .\tests\run_windows_tests.ps1 -Setup     # 重新设置环境
   .\tests\run_windows_tests.ps1 -Clean     # 清理环境
   .\tests\run_windows_tests.ps1 full       # 完整测试

"@ -ForegroundColor Green
}

# 执行主函数
Main 